package cn.mall.framework.biz;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.Resource;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang.StringUtils;

import cn.mall.common.relation.RelationKit;
import cn.mall.framework.biz.bean.ErrorInfo;
import cn.mall.framework.common.JsonKit;

@Slf4j
public class PublicBusinessProcessSynchronizer implements MessageListener {
	
	private ConcurrentHashMap<String, Thread> sleepMap = new ConcurrentHashMap<String, Thread>();
	private ConcurrentHashMap<String, String> resultMap = new ConcurrentHashMap<String, String>();
	
	@Resource
	private String jmsSrcUUID;
	@Resource
	private String callerRelationId;
	
	private static int WAIT_TIME = 30;

	public String processRequest(PublicServiceProcessAsync processor,
			Object object, String relationId,String srcUUID) {
		if (StringUtils.isNotBlank(relationId)) {
			// 异步调用
			return processor.processRequest(object, relationId, srcUUID);
		} else {
			// 同步调用
			Thread thread = Thread.currentThread();
			sleepMap.put(callerRelationId, thread);
			synchronized (thread) {
				processor.processRequest(object, callerRelationId, jmsSrcUUID);
				try {
					thread.wait(WAIT_TIME * 1000);
					sleepMap.remove(relationId);
					String result = resultMap.remove(callerRelationId);
					if (result != null) {
						return result;
					} else {
						return getErrorResp("调用超时");
					}
				} catch (InterruptedException e) {
					sleepMap.remove(callerRelationId);
					resultMap.remove(callerRelationId);
					return getErrorResp("调用中断");
				}
			}
		}
	}

	@Override
	public void onMessage(Message message) {
		RelationKit.initRelationFrom(message);
		if (!(message instanceof TextMessage)) {
			log.error("消息类型必须是TextMessage");
			return;
		}
		try {
			String relationId = message.getJMSCorrelationID();
			Thread thread = sleepMap.get(relationId);
			if (thread != null) {
				resultMap.put(relationId, ((TextMessage) message).getText());
				synchronized (thread) {
					thread.notifyAll();
				}
			} else {
				log.info("调用方已主动超时");
			}
		} catch (Exception e) {
			log.error("", e);
		}
	}

	private String getErrorResp(String msg) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("errCode", ErrorInfo.TIME_OUT_INFO);
		map.put("errInfo", msg);
		return JsonKit.map2json(map);
	}
}
